#include <windows.h>
#include "..\pluginapi.h"

// Dialog control defines
#define IDD_LICENSEA  102  // Default license page

#define IDD_LICENSEB  108  // License page with "Accept" check-box
#define IDC_LB_CHECK  1034 // Check-box

#define IDD_LICENSEC  109  // License page with "Accept" and "Decline" radio-buttons
#define IDC_LC_RB1    1034 // Radio-button 1
#define IDC_LC_RB2    1035 // Radio-button 2

#define IDC_NEXT      1    // Next button
#define IDC_BACK      3    // Back button

#define IDC_LICENSE   1000 // License RichEdit20A


#ifndef SetWindowLongPtr
#define SetWindowLongPtr SetWindowLong
#endif

#ifndef GetWindowLongPtr
#define GetWindowLongPtr GetWindowLong
#endif

#ifndef GWLP_WNDPROC
#define GWLP_WNDPROC GWL_WNDPROC
#endif

#ifndef DWLP_DLGPROC
#define DWLP_DLGPROC DWL_DLGPROC
#endif

// Global variables
HINSTANCE g_hInstance;
UINT g_uMsgCreate;

HWND g_hWndParent, g_hChildWnd;

HWND g_hLicense, g_hCheck, g_hNext;

// Declare window and dialog procedures
WNDPROC WndProcOld;
DLGPROC DlgProcOld;

// Callback Function: This handles window messages and notifications sent from the child window
static BOOL CALLBACK WndProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  if (uMsg == g_uMsgCreate)
  {
    g_hCheck   = GetDlgItem(g_hChildWnd, IDC_LB_CHECK);
    g_hNext    = GetDlgItem(g_hWndParent, IDC_NEXT);

    // Enable next button.
    EnableWindow(g_hNext, TRUE);

    return FALSE;
  }
  // Call the default window procedure if we haven't used our own
  return CallWindowProc((WNDPROC)WndProcOld, hWndDlg, uMsg, wParam, lParam);
}

// Callback Function: This handles messages and notifications sent from controls
static BOOL CALLBACK DlgProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  if (uMsg == WM_COMMAND)
  {
    if (LOWORD(wParam) == IDC_LB_CHECK || LOWORD(wParam) == IDC_LC_RB2)
    {
     // Enable next button on controls where it gets disabled by NSIS dlgproc.
      EnableWindow(g_hNext, TRUE);
      return FALSE;
    }
  }

  return CallWindowProc((WNDPROC)DlgProcOld, hWndDlg, uMsg, wParam, lParam);
}

// NSIS Function: Enables plugin
extern "C"
void __declspec(dllexport) Set(HWND hWndParent, int string_size,
                                      char *variables, stack_t **stacktop,
                                      extra_parameters *extra)
{
  g_hWndParent = hWndParent;

  // Set up global variable values
  g_hChildWnd       = FindWindowEx(hWndParent, NULL, "#32770", NULL);
  g_uMsgCreate      = RegisterWindowMessage("optional license create");

  // Assign our child window procedure
  if (!WndProcOld)
  {
    WndProcOld     = (WNDPROC)SetWindowLongPtr(g_hChildWnd, GWLP_WNDPROC, (LONG)WndProc);
    SendMessage(g_hChildWnd, g_uMsgCreate, TRUE, (LPARAM)g_hChildWnd);
  }

  // Assign our child procedure
  if (!DlgProcOld)
    DlgProcOld     = (DLGPROC)SetWindowLongPtr(g_hChildWnd, DWLP_DLGPROC, (LONG)DlgProc);
}


// NSIS Function: Returns state
extern "C"
void __declspec(dllexport) State(HWND hWndParent, int string_size,
                                      char *variables, stack_t **stacktop,
                                      extra_parameters *extra)
{
  EXDLL_INIT();
  pushint(SendMessage(g_hCheck, BM_GETCHECK, 0, 0));
}


// NSIS Function: Unloads plugin
extern "C"
void __declspec(dllexport) Unload(HWND hWndParent, int string_size,
                                      char *variables, stack_t **stacktop,
                                      extra_parameters *extra)
{
  SetWindowLongPtr(g_hChildWnd, GWLP_WNDPROC, (LONG)WndProcOld);
  SetWindowLongPtr(g_hChildWnd, DWLP_DLGPROC, (LONG)DlgProcOld);
}


BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
  g_hInstance = (HINSTANCE)hInst;
  return TRUE;
}